﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TranslatorService.Speech;
using System.IO;
using System.Diagnostics;
using System.Globalization;

namespace TranslatorService.WPFExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string CLIENT_ID = "";
        private const string CLIENT_SECRET = "";

        private SpeechSynthesizer speech;

        public MainWindow()
        {
            InitializeComponent();

            if (string.IsNullOrEmpty(CLIENT_ID) || string.IsNullOrEmpty(CLIENT_SECRET))
            {
                MessageBox.Show("You must obtain a Client ID and Secret in order to use this application. Please visit Azure DataMarket at https://datamarket.azure.com/developer/applications to get one.\r\nThen, go to https://datamarket.azure.com/dataset/1899a118-d202-492c-aa16-ba21c33c06cb and subscribe the Microsoft Translator Service.", this.Title, MessageBoxButton.OK, MessageBoxImage.Exclamation);
                this.Close();
            }

            // Create the object that retrieves speech streams.
            speech = new SpeechSynthesizer(CLIENT_ID, CLIENT_SECRET);
            speech.AudioFormat = SpeakStreamFormat.Wave;
            speech.AudioQuality = SpeakStreamQuality.MaxQuality;
            speech.AutoDetectLanguage = true;
            speech.AutomaticTranslation = true;

            speech.GetLanguagesCompleted += new EventHandler<GetLanguagesEventArgs>(speech_GetLanguagesCompleted);
            speech.SpeakCompleted += new EventHandler<SpeechEventArgs>(speech_SpeakCompleted);
            speech.TranslateCompleted += new EventHandler<TranslateEventArgs>(speech_TranslateCompleted);
            speech.DetectLanguageCompleted += new EventHandler<DetectLanguageEventArgs>(speech_DetectLanguageCompleted);
        }

        private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            Process.Start(e.Uri.ToString());
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Retrieves the list of supported languages.
            this.StartElaboration("Retrieving the list of supported languages...");
            speech.GetLanguagesAsync();
        }

        #region Get Languages

        private void speech_GetLanguagesCompleted(object sender, GetLanguagesEventArgs e)
        {
            this.FinishElaboration(e.Error);
            if (e.Error == null)
            {
                var languages = e.Languages.ToDictionary(lang => lang, lang => CultureInfo.GetCultureInfo(lang).DisplayName);
                cboLanguages.ItemsSource = languages.OrderBy(i => i.Value);
                cboLanguages.DisplayMemberPath = "Value";
                cboLanguages.SelectedValuePath = "Key";

                cboLanguages.Text = CultureInfo.CurrentCulture.DisplayName;
            }
        }

        #endregion

        #region Speak

        private void btnSpeak_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtText.Text))
                return;

            this.StartElaboration("Submitting request...");
            speech.AutoDetectLanguage = chkAutoDetectLanguage.IsChecked.Value;
            speech.AutomaticTranslation = chkAutomaticTranslation.IsChecked.Value;

            // If auto language detection is enabled, don't use the selected language, because it will be auto-detected.
            string language = speech.AutoDetectLanguage ? null : cboLanguages.SelectedValue.ToString();
            speech.SpeakAsync(txtText.Text, language);
        }

        private void speech_SpeakCompleted(object sender, SpeechEventArgs e)
        {
            this.FinishElaboration(e.Error);
        }

        #endregion

        #region Translate

        private void btnTranslate_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtText.Text))
                return;

            this.StartElaboration("Submitting request...");
            txtTranslatedText.Text = string.Empty;
            speech.TranslateAsync(txtText.Text, cboLanguages.SelectedValue.ToString());
        }

        private void speech_TranslateCompleted(object sender, TranslateEventArgs e)
        {
            this.FinishElaboration(e.Error);
            if (e.Error == null)
                txtTranslatedText.Text = e.TranslatedText;
            else
                txtTranslatedText.Text = string.Empty;
        }

        #endregion

        #region Detect Language

        private void btnDetectLanguage_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtText.Text))
                return;

            this.StartElaboration("Submitting request...");

            speech.DetectLanguageAsync(txtText.Text);
        }

        private void speech_DetectLanguageCompleted(object sender, DetectLanguageEventArgs e)
        {
            this.FinishElaboration(e.Error);
            if (e.Error == null)
                txtMessage.Text = string.Format("The language of the text is: {0} - {1}", e.Language, CultureInfo.GetCultureInfo(e.Language).DisplayName);
        }

        #endregion

        #region Helper methods

        private void StartElaboration(string message)
        {
            this.Cursor = Cursors.AppStarting;
            txtMessage.Text = message;
        }

        private void FinishElaboration(Exception error)
        {
            this.Cursor = Cursors.Arrow;

            if (error != null)
                txtMessage.Text = error.Message;
            else
                txtMessage.Text = string.Empty;
        }

        private void chkAutoDetectLanguage_Click(object sender, RoutedEventArgs e)
        {
            if (cboLanguages != null)
            {
                cboLanguages.IsEnabled = !chkAutoDetectLanguage.IsChecked.Value;
                chkAutomaticTranslation.IsEnabled = !chkAutoDetectLanguage.IsChecked.Value;
            }
        }

        #endregion

    }
}
